home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Almathera Ten Pack 2: CDPD 1
/
Almathera Ten on Ten - Disc 2: CDPD 1.iso
/
pd
/
476-500
/
500
/
wiconify
/
wiconsetter.lzh
/
wIconSetter
/
Source
/
wIconFile.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-04-19
|
15KB
|
524 lines
/*
* WICONSETTER A companion utility to wIconify. wIconSetter allows
* you to specify custom icons for windows ans screens
* that normally use the default icons.
*
* wIconFile.c Reads the initialization file.
*
* Copyright 1990 by Davide P. Cervone, all rights reserved.
* You may use this code, provided this copyright notice is kept intact.
*/
#include "wIconFile.h"
static char *Any = "[ANY]";
static char *Null = "[NULL]";
extern char **ComName; /* current command table */
#define NAME(p) ((p->Name)?((p->Name == NAME_ANY)?Any:p->Name):Null)
/*
* StartCommand()
*
* Set up anything needed to begin the specified command. Usually this
* means clear any previous value of the appropriate variables or flags,
* and possibly recording the command type for future reference.
*
* PROGRAM:
* If a previous program or define is in effect, check that an icon was
* provided, and if not, give an error.
* Allocate a new program structure.
*
* SCREEN:
* If a previous screen or define is in effect, check that an icon was
* provided, and if not, give an error.
* Allocate a new screen structure.
*
* WINDOW:
* If a previous define is in effect and no icon was give, error
* Get a new window structure.
*
* ICON:
* Check that there is somewhere to put the icon.
*
* IMAGE, SELECT, MASK:
* Clear the image area and check that there is somewhere to put the icon.
*
* FLAGS:
* Check that there is somewhere to put the flags,
* If so, clear the flag area.
*
* POSITION, NAME:
* Check that there is somewhere to put the position or name.
*
* DEFINE:
* If a previous program or define is in effect, check to be sure that
* an icon was provided. Error if not.
* Get a new definition structure.
*
* If an icon was started but there was no place to put it, error.
*/
static int StartCommand(theCommand)
int theCommand;
{
int NeedIcon = FALSE;
switch(theCommand)
{
case COM_PROGRAM:
if ((PROGRAM || DEFINE) && NoIcon) NoIconError();
GetNewProgram();
break;
case COM_SCREEN:
if (((ScreenPtr && SCREEN) || DEFINE) && NoIcon) NoIconError();
GetNewScreen();
break;
case COM_WINDOW:
if (DEFINE && NoIcon) NoIconError();
GetNewWindow();
break;
case COM_ICON:
NeedIcon = CheckForIcon();
if (NeedIcon) theCommand = NULL;
NoIcon = FALSE;
break;
case COM_IMAGE:
case COM_SELECT:
case COM_MASK:
ClearBitMap();
ImageType = theCommand;
NeedIcon = CheckForIcon();
NoIcon = FALSE;
break;
case COM_FLAGS:
NeedIcon = CheckForIcon();
if (IconPtr)
{
ICON.Flags = 0;
CopyIconData(COM_FLAGS);
} else {
theCommand = NULL;
}
NoIcon = FALSE;
break;
case COM_POSITION:
case COM_NAME:
NeedIcon = CheckForIcon();
if (NeedIcon) theCommand = NULL;
NoIcon = FALSE;
break;
case COM_DEFINE:
if ((PROGRAM || DEFINE) && NoIcon) NoIconError();
GetNewDefine();
break;
}
if (NeedIcon)
{
ShowError("Command must follow a DEFINE or WINDOW command");
SkipLine();
}
return(theCommand);
}
/*
* ContinueCommand()
*
* Do the right thing for each kind of command:
*
* PROGRAM:
* If a program structure was allocated,
* Get the name of the program
* If it was NULL, give an error
* If it was the wIconify process, give an error
* Otherwise, check that the program was not already defined
* End the command
*
* SCREEN:
* If a screen structure was allocated,
* Read the screen name.
* Check if the screen matches one that already is defined.
* If so, show an error
* End the command
*
* WINDOW:
* If the window structure has been allocated,
* Read the window name
* Check if the name matches one that is already defined
* If so, show an error.
* End the command
*
* ICON:
* If the next word is FROM,
* Get the next word (the Icon file name) and read the file
* Otherwise
* Get the full line as the icon's name
* Find the icon in the definition list, and copy it, if it exists,
* Otherwise show an error
* End the command
*
* IMAGE, SELECT, MASK:
* Read the next line of the image; we must be at the end of the line
*
* FLAGS:
* Read the next word as a flag and copy it to the current icon
*
* POSITION:
* Get the specified position and copy it to the icon
* We must be at the end of the line, and end the command
*
* NAME:
* If the icon has a previous (allocated) name, free it
* Clear the pointer and read a new name
* If the name was allocated, mark it as such
* Copy the name to the icon
* We must be at the end of the line, and end the command
*
* DEFINE:
* If the define structure was allocated,
* Read the definition name
* If it was NULL or ANY, show an error
* Otherwise, check if it matched a previously defined icon
* End the command
*
* If we are supposed to be at the end of the line but aren't,
* Give an error and skip the rest of the line.
*/
static int ContinueCommand(theCommand)
int theCommand;
{
int EndOfLine = FALSE;
ICONDEFINE *theDefine;
ICONWINDOW *theWindow;
ICONSCREEN *theScreen;
ICONPROGRAM *theProgram;
switch(theCommand)
{
case COM_PROGRAM:
if (PROGRAM)
{
ReadName(&(PROGRAM->Name));
if (PROGRAM->Name == NAME_NULL)
{
ShowError("NULL is illegal as a PROGRAM name");
CopyName(&(PROGRAM->Name),Null);
} else if (stricmp(PROGRAM->Name,ICONPROCNAME) == 0) {
ShowError("wIcoinfy process itself can not be specified");
CopyName(&(PROGRAM->Name),Null);
} else {
theProgram = FirstProgram;
while (theProgram != PROGRAM)
{
if (MATCH(theProgram->Name,PROGRAM->Name))
{
ShowError("Program '%s' defined twice",NAME(PROGRAM));
theProgram = PROGRAM;
} else theProgram = theProgram->Next;
}
}
}
theCommand = COM_NONE;
break;
case COM_SCREEN:
if (SCREEN)
{
ReadName(&(SCREEN->Name));
theScreen = PROGRAM->Screen;
while (theScreen != SCREEN)
{
if (PREFIXMATCH(theScreen->Name,SCREEN->Name))
{
if (MATCH(theScreen->Name,SCREEN->Name))
ShowError("Screen '%s' defined twice",NAME(SCREEN));
else
ShowError("Screen '%s' matches '%s' already defined",
NAME(SCREEN),NAME(theScreen));
theScreen = SCREEN;
} else theScreen = theScreen->Next;
}
}
theCommand = COM_NONE;
break;
case COM_WINDOW:
if (WINDOW)
{
ReadName(&(WINDOW->Name));
theWindow = SCREEN->Window;
while (theWindow != WINDOW)
{
if (PREFIXMATCH(theWindow->Name,WINDOW->Name))
{
if (MATCH(theWindow->Name,WINDOW->Name))
ShowError("Window '%s' defined twice",NAME(WINDOW));
else
ShowError("Window '%s' matches '%s' already defined",
NAME(WINDOW),NAME(theWindow));
theWindow = WINDOW;
} else theWindow = theWindow->Next;
}
}
theCommand = COM_NONE;
break;
case COM_ICON:
if (WORDMATCH("FROM"))
{
ReadNextWord();
ReadIconFile();
} else {
ReadFullLine();
theDefine = FindDefine(Word);
if (theDefine) CopyDefine(theDefine);
else ShowError("Undefined Icon '%s'",Word);
}
theCommand = COM_NONE;
break;
case COM_IMAGE:
case COM_SELECT:
case COM_MASK:
ReadImageLine(BitMapLine++);
EndOfLine = TRUE;
break;
case COM_FLAGS:
ReadIconFlags(&(ICON.Flags));
CopyIconData(COM_FLAGS);
break;
case COM_POSITION:
ReadPosition(&(ICON.x),&(ICON.y));
CopyIconData(COM_POSITION);
EndOfLine = TRUE;
theCommand = COM_NONE;
break;
case COM_NAME:
if (IconPtr->Flags & IW_NAME) FREECHAR(ICON.Name);
ICON.Name = NULL; ReadName(&(ICON.Name));
if (ICON.Name != NAME_NULL && ICON.Name != NAME_ANY)
IconPtr->Flags |= IW_NAME;
CopyIconData(COM_NAME);
EndOfLine = TRUE;
theCommand = COM_NONE;
break;
case COM_DEFINE:
if (DEFINE)
{
ReadName(&(DEFINE->Name));
if (DEFINE->Name == NAME_NULL || DEFINE->Name == NAME_ANY)
{
ShowError("NULL and ANY are illegal as ICON names");
CopyName(&(DEFINE->Name),Null);
} else {
theDefine = FirstDefine;
while (theDefine != DEFINE)
{
if (MATCH(theDefine->Name,DEFINE->Name))
{
ShowError("Icon '%s' defined twice",NAME(DEFINE));
theDefine = DEFINE;
} else theDefine = theDefine->Next;
}
}
}
theCommand = COM_NONE;
break;
}
if (EndOfLine && NextChar != '\n')
{
ReadNextWord();
ShowError("'%s' seen where End-of-Line was expected",Word);
SkipLine();
}
return(theCommand);
}
/*
* EndCommand()
*
* Finish the command that is in progress, and check that all parameters,
* etc, have been included. If not, give a message about what was
* expected to be seen. For the image commands, copy the image to the
* correct image pointer.
*/
static void EndCommand(theCommand,newCommand)
int theCommand,newCommand;
{
char *Wanted = NULL;
switch(theCommand)
{
case COM_PROGRAM:
if (PROGRAM && PROGRAM->Name == NAME_ANY)
Wanted = "a Program Name", PROGRAM->Name = "";
break;
case COM_SCREEN:
if (ScreenPtr && SCREEN && SCREEN->Name == NAME_ANY)
Wanted = "a Screen Name", CopyName(SCREEN->Name,Null);
break;
case COM_WINDOW:
if (WindowPtr && WINDOW && WINDOW->Name == NAME_ANY)
Wanted = "a Window Name", CopyName(WINDOW->Name,Null);
break;
case COM_IMAGE:
if (BitMapLine == 0) Wanted = "Image Data";
else if (IconPtr)
{
if (IconPtr->Flags & IW_IMAGE) FreeImage(ICON.Image);
SetImage(&(ICON.Image)); IconPtr->Flags |= IW_IMAGE;
CopyIconData(COM_IMAGE);
}
break;
case COM_SELECT:
if (BitMapLine == 0) Wanted = "Image Data";
else if (IconPtr)
{
if (IconPtr->Flags & IW_SELECT) FreeImage(ICON.Select);
SetImage(&(ICON.Select)); IconPtr->Flags |= IW_SELECT;
CopyIconData(COM_SELECT);
}
break;
case COM_MASK:
if (BitMapLine == 0) Wanted = "Mask Data";
else if (IconPtr)
{
if (IconPtr->Flags & IW_MASK) FreeImage(MASK);
SetImage(MaskPtr); IconPtr->Flags |= IW_MASK;
if (MASK) ICON.Mask = MASK->ImageData;
CopyIconData(COM_MASK);
}
break;
case COM_ICON:
Wanted = "an Icon Name or FROM File";
break;
case COM_POSITION:
Wanted = "an (x,y) position";
break;
case COM_NAME:
Wanted = "an Icon Name";
break;
case COM_DEFINE:
if (DEFINE && DEFINE->Name == NULL)
Wanted = "an Icon Name", DEFINE->Name = "";
break;
}
if (Wanted)
{
if (newCommand > COM_LAST) Expected(Wanted); else
ShowError("Keyword '%s' seen where %s was expected",
ComName[newCommand],Wanted);
}
}
/*
* ReadFile()
*
* While there is more data in the file,
* Read the next word from the file and interpret it as a command
* If the word was a command and there is an old command in progress
* End the old command
* If the new command is
* Not a command:
* If there is a command in progress, do it to the current word,
* Otherwise give an error and skip to the next line.
* Unknown:
* Give a message and skip to the next line.
* An End-Of-File:
* If an icon file is currently being read, close it,
* Otherwise set the end-of-file marker to TRUE.
* Anything else (i.e., a legitimate command):
* Mark the command as the old command, and setup whatever is needed.
*/
static void ReadFile(theFile)
APTR theFile;
{
int PendingCommand = COM_NONE;
int NewCommand;
int EOF = FALSE;
while (!EOF)
{
NewCommand = ReadCommand();
if (NewCommand != COM_NONE && PendingCommand != COM_NONE)
EndCommand(PendingCommand,NewCommand), PendingCommand = COM_NONE;
switch(NewCommand)
{
case COM_NONE:
if (PendingCommand != COM_NONE)
PendingCommand = ContinueCommand(PendingCommand);
else
Expected("a Command Keyword"),
SkipLine();
break;
case COM_UNKNOWN:
ShowError("Unrecognized Command '%s'",Word);
SkipLine();
break;
case COM_EOF:
if (IconFileOpen) EndIconFile();
else EOF = TRUE;
break;
default:
PendingCommand = StartCommand(NewCommand);
break;
}
}
}
/*
* ReadInitFile()
*
* Try to open the primary initialization file,
* If unsuccessful, try the secondary file.
* If a file was openned,
* Read the file and then close it.
* Sort the program linked-list.
*/
void ReadInitFile(Name1,Name2)
char *Name1,*Name2;
{
if (Name1)
{
if (OpenFile(Name1) == FALSE && Name2) OpenFile(Name2);
if (InFile)
{
ReadFile(InFile);
CloseFile(InFile);
SortPrograms();
} else DoExit("Can't open initialization file '%s'",Name1);
}
}